Skip to content

x509attr: check for errors of sk_ASN1_TYPE_push() & use reserve call#1034

Merged
rhenium merged 2 commits intoruby:masterfrom
ndossche:clesss-9
Apr 29, 2026
Merged

x509attr: check for errors of sk_ASN1_TYPE_push() & use reserve call#1034
rhenium merged 2 commits intoruby:masterfrom
ndossche:clesss-9

Conversation

@ndossche
Copy link
Copy Markdown
Contributor

See individual commits.

This function returns 0 on error. The main error condition is reallocation, so use a reserve call to avoid reallocations as well.

This was found by a hybrid static-dynamic analyser that looks for inconsistent handling of error checks in bindings.

This function returns 0 on error.
Comment thread ext/openssl/ossl_x509attr.c Outdated
GetX509Attr(self, attr);
count = X509_ATTRIBUTE_count(attr);
/* there is no X509_ATTRIBUTE_get0_set() :( */
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you check the availability of the function in ext/openssl/extconf.rb instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do that after lunch. THanks, I'm relatively new to Ruby extension development so wasn't familiar with this.

This should avoid reallocations and prevent the main error condition of
the push call.
@rhenium rhenium merged commit 46b1093 into ruby:master Apr 29, 2026
47 checks passed
@botovq
Copy link
Copy Markdown
Contributor

botovq commented May 2, 2026

It doesn't really matter here since we know sk != NULL, but arguably the correct error check for sk_push is still <= 0 because it can return -1 in OpenSSL 1.1.1 and LibreSSL (for a NULL stack).

I repeat what I mentioned elsewhere: I really wish @ndossche would stop pushing the use of sk_new_reserve() into the ecosystem. It is a really bad API with dangerous semantics that isn't portable across libcryptos for good reason: if you use it to simplify error checking, your code is badly written and should be fixed; otherwise it's just a micro-optimization that isn't worth the extra API call and #ifdef. Stacks are arrays of pointers using exponential scaling (doubling on resize or similar), so the reallocations are neither frequent nor expensive. Stacks very rarely grow into the thousands. So sk_new_reserve() doesn't save more than a handful of reallocations/memcpys (expecially here, where it is about attributes of which there never are more than a handful at the same time).

@ndossche
Copy link
Copy Markdown
Contributor Author

ndossche commented May 2, 2026

@botovq jeez, I pushed for the use of reserve like twice or so. I agree you need the push check but I disagree with your opinion about it being an unnecessary API. I'll stop pushing reserve if that makes you happy and if that means you leave me alone rather than apparently follow me around on github.

@botovq
Copy link
Copy Markdown
Contributor

botovq commented May 2, 2026

@ndossche Yes, two of the three uses I know outside of OpenSSL itself...

Just to be clear: I do not follow you around specifically and I think the work prompted by your static analyzer is really great. What I do is I look at downstream changes and point out things that aren't done ideally. But yes, if you stop using the reserve API this will decrease the likelihood of me complaining.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants